import 'package:flutter/material.dart';
import 'package:cached_network_image/cached_network_image.dart';

import '../core/api_service.dart';
import '../core/douban_service.dart';
import '../core/models.dart';
import '../core/sites.dart';
import 'player_page.dart';
import '../core/theme_config.dart';
import 'package:provider/provider.dart';
import 'package:http/http.dart' as http;

class DetailPage extends StatefulWidget {
  final VideoSite? site;
  final int? id;
  final String? keyword; // 当存在时，并发从全部站点搜索同名详情并聚合
  final List<VodDetail>? aggregated; // 预聚合的详情数据
  const DetailPage({super.key, this.site, this.id, this.keyword, this.aggregated});

  @override
  State<DetailPage> createState() => _DetailPageState();
}

class _DetailPageState extends State<DetailPage> {
  late ApiService _service;
  VodDetail? _detail;
  List<VodDetail> _aggregated = [];
  bool _loading = false;
  
  // 播放相关状态变量
  bool _isSearching = false;
  List<VodDetail> _searchResults = [];
  int _searchTotal = 0;
  int _searchDone = 0;

  @override
  void initState() {
    super.initState();
    if (widget.site != null) {
      _service = ApiService(widget.site!);
    }
    _initializeAndLoad();
  }

  Future<void> _initializeAndLoad() async {
    // 确保站点数据已加载
    if (kVideoSites.isEmpty) {
      await SitesRepository.loadSites();
    }
    await _load();
  }

  Future<void> _load() async {
    if ((widget.keyword ?? '').isNotEmpty) {
      await _loadByKeyword();
    } else {
      await _loadDetail();
    }
  }

  Future<void> _loadByKeyword() async {
    setState(() => _loading = true);
    try {
      print("关键字搜索: ${widget.keyword}");
      
      // 只调用豆瓣搜索和详情获取
      final doubanDetail = await _getDoubanDetailByKeyword(widget.keyword!);
      
      if (doubanDetail != null) {
        _aggregated = [doubanDetail];
        _detail = doubanDetail;
      } else {
        _aggregated = [];
        _detail = null;
      }
      
      if (mounted) setState(() {});
    } catch (e) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('加载详情失败: $e')),
      );
    } finally {
      setState(() => _loading = false);
    }
  }

  Future<void> _loadDetail() async {
    setState(() => _loading = true);
    try {
      print('开始加载详情页');
      if (widget.aggregated != null) {
        _aggregated = widget.aggregated!;
        _detail = _aggregated.isNotEmpty ? _aggregated.first : null;
      } else if (widget.site != null && widget.id != null) {
        // 对于直接ID访问，异步并发调用所有资源站和豆瓣API
        final futures = <Future<VodDetail?>>[];
        
        // 并发调用所有原始资源站
        futures.addAll(await _getAllSiteDetailFutures());
        
        // 如果ID看起来像豆瓣ID（纯数字），尝试获取豆瓣详情
        if (widget.id.toString().length >= 6 && int.tryParse(widget.id.toString()) != null) {
          futures.add(_getDoubanDetailById(int.parse(widget.id.toString())));
        }
        
        final results = await Future.wait(futures);
        final validResults = results.whereType<VodDetail>().toList();
        
        // 智能聚合和排序数据
        _aggregated = _aggregateAndSortResults(validResults);
        
        // 选择最佳详情作为主要显示
        _detail = _selectBestDetail(_aggregated);
      }
      if (mounted) setState(() {});
    } catch (e) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('加载详情失败: $e')),
      );
    } finally {
      setState(() => _loading = false);
    }
  }

  /// 智能聚合和排序结果
  List<VodDetail> _aggregateAndSortResults(List<VodDetail> results) {
    if (results.isEmpty) return results;
    
    // 按照数据质量排序：有图片 > 有内容 > 有播放源 > 其他
    results.sort((a, b) {
      int scoreA = _calculateDetailScore(a);
      int scoreB = _calculateDetailScore(b);
      return scoreB.compareTo(scoreA); // 降序排列
    });
    
    return results;
  }

  /// 计算详情数据的质量分数
  int _calculateDetailScore(VodDetail detail) {
    int score = 0;
    
    // 有图片 +10分
    if ((detail.pic ?? '').isNotEmpty) score += 10;
    
    // 有内容描述 +8分
    if ((detail.content ?? '').isNotEmpty) score += 8;
    
    // 有播放源 +6分
    if (detail.playSources.isNotEmpty) score += 6;
    
    // 有演员信息 +4分
    if ((detail.actor ?? '').isNotEmpty) score += 4;
    
    // 有导演信息 +3分
    if ((detail.director ?? '').isNotEmpty) score += 3;
    
    // 有年份信息 +2分
    if ((detail.year ?? '').isNotEmpty) score += 2;
    
    // 有地区信息 +1分
    if ((detail.area ?? '').isNotEmpty) score += 1;
    
    return score;
  }

  /// 选择最佳详情作为主要显示
  VodDetail? _selectBestDetail(List<VodDetail> aggregated) {
    if (aggregated.isEmpty) return null;
    
    // 已经按质量排序，直接返回第一个
    return aggregated.first;
  }

  @override
  Widget build(BuildContext context) {
    final d = _detail;
    final themeConfig = Provider.of<ThemeConfig>(context);
    return Scaffold(
      appBar: AppBar(
        title: Text(d?.name ?? '详情'),
        backgroundColor: themeConfig.currentGradient.colors.first,
        elevation: 0,
        foregroundColor: themeConfig.currentTextColor,
      ),
      body: Container(
        decoration: const BoxDecoration(
          gradient: LinearGradient(
            begin: Alignment.topCenter,
            end: Alignment.bottomCenter,
            colors: [
              Color(0xFFF8FAFC),
              Color(0xFFE2E8F0),
            ],
          ),
        ),
        child: _loading
            ? _buildLoadingWidget()
            : d == null
                ? const Center(child: Text('无数据'))
                : SingleChildScrollView(
                    child: Padding(
                      padding: const EdgeInsets.all(12.0),
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Card(
                            elevation: 4,
                            color: Colors.white,
                            shadowColor: Colors.black.withOpacity(0.1),
                            shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
                            child: Padding(
                            padding: const EdgeInsets.all(12.0),
                            child: LayoutBuilder(
                              builder: (context, constraints) {
                                final isWideScreen = constraints.maxWidth > 500;
                                
                                if (isWideScreen) {
                                  // 宽屏：水平布局
                                  return Row(
                                    crossAxisAlignment: CrossAxisAlignment.start,
                                    children: [
                                      _buildPosterImage(d),
                                      const SizedBox(width: 16),
                                      Expanded(child: _buildMovieInfo(d)),
                                    ],
                                  );
                                } else {
                                  // 窄屏：垂直布局
                                  return Column(
                                    crossAxisAlignment: CrossAxisAlignment.start,
                                    children: [
                                      Row(
                                        crossAxisAlignment: CrossAxisAlignment.start,
                                        children: [
                                          _buildPosterImage(d, isCompact: true),
                                          const SizedBox(width: 12),
                                          Expanded(child: _buildMovieInfo(d, isCompact: true)),
                                        ],
                                      ),
                                    ],
                                  );
                                }
                              },
                            ),
                          ),
                        ),
                        const SizedBox(height: 10),                                           
                        // 播放按钮
                        _buildPlayButton(),                        
                        const SizedBox(height: 10),
                        // 导演和演员卡片（并排显示）
                        if (d.directors.isNotEmpty || d.casts.isNotEmpty)
                          Card(
                            elevation: 4,
                            color: Colors.white,
                            shadowColor: Colors.black.withOpacity(0.1),
                            shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
                            child: Padding(
                              padding: const EdgeInsets.all(12.0),
                              child: LayoutBuilder(
                                builder: (context, constraints) {
                                  final isWideScreen = constraints.maxWidth > 600;
                                  
                                  if (isWideScreen) {
                                    // 宽屏：导演和演员并排显示
                                    return Row(
                                      crossAxisAlignment: CrossAxisAlignment.start,
                                      children: [
                                        // 导演部分
                                        if (d.directors.isNotEmpty)
                                          Expanded(
                                            child: Column(
                                              crossAxisAlignment: CrossAxisAlignment.start,
                                              children: [
                                                Text('导演', style: Theme.of(context).textTheme.titleMedium?.copyWith(fontWeight: FontWeight.w600)),
                                                const SizedBox(height: 12),
                                                SizedBox(
                                                  height: 120,
                                                  child: ListView.builder(
                                                    scrollDirection: Axis.horizontal,
                                                    itemCount: d.directors.length,
                                                    itemBuilder: (context, index) {
                                                      final director = d.directors[index];
                                                      return _buildPersonCard(director);
                                                    },
                                                  ),
                                                ),
                                              ],
                                            ),
                                          ),
                                        
                                        if (d.directors.isNotEmpty && d.casts.isNotEmpty)
                                          const SizedBox(width: 16),
                                        
                                        // 演员部分
                                        if (d.casts.isNotEmpty)
                                          Expanded(
                                            child: Column(
                                              crossAxisAlignment: CrossAxisAlignment.start,
                                              children: [
                                                Text('演员', style: Theme.of(context).textTheme.titleMedium?.copyWith(fontWeight: FontWeight.w600)),
                                                const SizedBox(height: 12),
                                                SizedBox(
                                                  height: 120,
                                                  child: ListView.builder(
                                                    scrollDirection: Axis.horizontal,
                                                    itemCount: d.casts.length,
                                                    itemBuilder: (context, index) {
                                                      final cast = d.casts[index];
                                                      return _buildPersonCard(cast);
                                                    },
                                                  ),
                                                ),
                                              ],
                                            ),
                                          ),
                                      ],
                                    );
                                  } else {
                                    // 窄屏：垂直堆叠显示
                                    return Column(
                                      crossAxisAlignment: CrossAxisAlignment.start,
                                      children: [
                                        // 导演部分
                                        if (d.directors.isNotEmpty) ...[
                                          Text('导演', style: Theme.of(context).textTheme.titleMedium?.copyWith(fontWeight: FontWeight.w600)),
                                          const SizedBox(height: 12),
                                          SizedBox(
                                            height: 120,
                                            child: ListView.builder(
                                              scrollDirection: Axis.horizontal,
                                              itemCount: d.directors.length,
                                              itemBuilder: (context, index) {
                                                final director = d.directors[index];
                                                return _buildPersonCard(director);
                                              },
                                            ),
                                          ),
                                        ],
                                        
                                        if (d.directors.isNotEmpty && d.casts.isNotEmpty)
                                          const SizedBox(height: 16),
                                        
                                        // 演员部分
                                        if (d.casts.isNotEmpty) ...[
                                          Text('演员', style: Theme.of(context).textTheme.titleMedium?.copyWith(fontWeight: FontWeight.w600)),
                                          const SizedBox(height: 12),
                                          SizedBox(
                                            height: 120,
                                            child: ListView.builder(
                                              scrollDirection: Axis.horizontal,
                                              itemCount: d.casts.length,
                                              itemBuilder: (context, index) {
                                                final cast = d.casts[index];
                                                return _buildPersonCard(cast);
                                              },
                                            ),
                                          ),
                                        ],
                                      ],
                                    );
                                  }
                                },
                              ),
                            ),
                          ),                        
                        const SizedBox(height: 10),
                      ],
                    ),
                  ),
                ),
      ),
    );
  }

  Future<VodDetail?> _getDoubanDetailByKeyword(String keyword) async {
    try {
      // 先通过豆瓣搜索API找到匹配的电影
      final searchResults = await DoubanService.searchMovies(
        query: keyword,
        start: 0,
        count: 5,
      );
      
      if (searchResults.isNotEmpty) {
        // 获取第一个搜索结果的详情
        final movieId = searchResults.first.id;
        final doubanDetail = await DoubanService.getMovieDetail(movieId);
        return doubanDetail;
      }
      return null;
    } catch (e) {
      print('豆瓣API调用错误: $e');
      return null;
    }
  }

  Future<VodDetail?> _getDoubanDetailById(int id) async {
    try {
      final doubanDetail = await DoubanService.getMovieDetail(id);
      return doubanDetail;
    } catch (e) {
      print('豆瓣API调用错误: $e');
      return null;
    }
  }

  Future<List<Future<VodDetail?>>> _getAllSiteDetailFutures() async {
    final futures = <Future<VodDetail?>>[];
    if (widget.id != null) {
      // 为每个视频站点创建一个异步任务
      for (final site in kVideoSites) {
        futures.add(_getSiteDetailById(site, widget.id!));
      }
    }
    
    return futures;
  }

  Future<VodDetail?> _getSiteDetailById(VideoSite site, int id) async {
    try {
      final svc = ApiService(site);
      return await svc.fetchDetail(id);
    } catch (e) {
      print('站点 ${site.name} 详情获取错误: $e');
      return null;
    }
  }

  Widget _buildPersonCard(DoubanPerson person) {
    return Container(
      width: 80,
      margin: const EdgeInsets.only(right: 12),
      child: Card(
        elevation: 2,
        color: Colors.white,
        shadowColor: Colors.black.withOpacity(0.05),
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
        child: Padding(
          padding: const EdgeInsets.all(6.0),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              ClipRRect(
                borderRadius: BorderRadius.circular(8),
                child: CachedNetworkImage(
                  imageUrl: person.avatars['medium'] ?? person.avatars['large'] ?? person.avatars['small'] ?? '',
                  width: 50,
                  height: 65,
                  fit: BoxFit.cover,
                  httpHeaders: const {
                    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
                    'Referer': 'https://movie.douban.com/',
                  },
                  placeholder: (context, url) => Container(
                    width: 50,
                    height: 65,
                    decoration: BoxDecoration(
                      color: Colors.grey[100],
                      borderRadius: BorderRadius.circular(8),
                    ),
                    child: Icon(Icons.person, size: 25, color: Colors.grey[400]),
                  ),
                  errorWidget: (context, url, error) => Container(
                    width: 50,
                    height: 65,
                    decoration: BoxDecoration(
                      color: Colors.grey[100],
                      borderRadius: BorderRadius.circular(8),
                    ),
                    child: Icon(Icons.person, size: 25, color: Colors.grey[400]),
                  ),
                ),
              ),
              const SizedBox(height: 4),
              Flexible(
                child: Text(
                  person.name,
                  style: Theme.of(context).textTheme.bodySmall?.copyWith(
                    fontWeight: FontWeight.w500,
                    fontSize: 11,
                  ),
                  textAlign: TextAlign.center,
                  maxLines: 2,
                  overflow: TextOverflow.ellipsis,
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

  Widget _buildPosterImage(VodDetail d, {bool isCompact = false}) {
    final width = isCompact ? 100.0 : 140.0;
    final height = isCompact ? 140.0 : 200.0;
    
    return ClipRRect(
      borderRadius: BorderRadius.circular(8),
      child: d.pic == null || d.pic!.isEmpty
          ? Container(width: width, height: height, color: Colors.black12, child: const Icon(Icons.movie, size: 60))
          : CachedNetworkImage(
              imageUrl: d.pic!,
              width: width,
              height: height,
              fit: BoxFit.cover,
              httpHeaders: const {
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
                'Referer': 'https://movie.douban.com/',
              },
              placeholder: (context, url) => Container(
                width: width,
                height: height,
                color: Colors.black12,
                child: const Center(child: CircularProgressIndicator()),
              ),
              errorWidget: (context, url, error) => Container(
                width: width,
                height: height,
                color: Colors.black12,
                child: const Icon(Icons.movie, size: 60),
              ),
            ),
    );
  }

  Widget _buildMovieInfo(VodDetail d, {bool isCompact = false}) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text(
          d.name, 
          style: Theme.of(context).textTheme.headlineSmall?.copyWith(
            fontWeight: FontWeight.w600,
            fontSize: isCompact ? 18 : null,
          ),
          maxLines: isCompact ? 2 : null,
          overflow: isCompact ? TextOverflow.ellipsis : null,
        ),
        if ((d.originalTitle ?? '').isNotEmpty && d.originalTitle != d.name)
          Text(
            d.originalTitle!, 
            style: Theme.of(context).textTheme.bodyMedium?.copyWith(color: Colors.grey[600]),
            maxLines: isCompact ? 1 : null,
            overflow: isCompact ? TextOverflow.ellipsis : null,
          ),
        const SizedBox(height: 8),
        
        // 豆瓣评分显示
        if (d.rating != null)
          Row(
            children: [
              Icon(Icons.star, color: Colors.amber, size: 20),
              const SizedBox(width: 4),
              Text(
                '${d.rating!.average.toStringAsFixed(1)}',
                style: Theme.of(context).textTheme.titleMedium?.copyWith(
                  fontWeight: FontWeight.bold,
                  color: Colors.amber[700],
                ),
              ),
              Text(' / 10', style: Theme.of(context).textTheme.bodySmall),
              if (d.ratingsCount != null && !isCompact)
                Text(' (${d.ratingsCount}人评价)', style: Theme.of(context).textTheme.bodySmall?.copyWith(color: Colors.grey[600])),
            ],
          ),
        const SizedBox(height: 8),
        
        // 类型和年份标签
        Wrap(
          spacing: 6,
          runSpacing: 6,
          children: [
            // 豆瓣类型标签
            if (d.genres.isNotEmpty)
              ...d.genres.take(isCompact ? 2 : 5).map((genre) => Chip(
                label: Text(genre, style: TextStyle(fontSize: isCompact ? 11 : 12)),
                backgroundColor: Colors.blue[50],
                labelStyle: TextStyle(color: Colors.blue[700]),
                materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
                visualDensity: VisualDensity.compact,
              )),
            // 传统字段作为备选
            if (d.genres.isEmpty && (d.typeName ?? '').isNotEmpty) 
              Chip(
                label: Text(d.typeName!, style: TextStyle(fontSize: isCompact ? 11 : 12)),
                materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
                visualDensity: VisualDensity.compact,
              ),
            if ((d.year ?? '').isNotEmpty) 
              Chip(
                label: Text(d.year!, style: TextStyle(fontSize: isCompact ? 11 : 12)),
                backgroundColor: Colors.green[50],
                labelStyle: TextStyle(color: Colors.green[700]),
                materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
                visualDensity: VisualDensity.compact,
              ),
            // 豆瓣国家标签
            if (d.countries.isNotEmpty)
              ...d.countries.take(isCompact ? 1 : 3).map((country) => Chip(
                label: Text(country, style: TextStyle(fontSize: isCompact ? 11 : 12)),
                backgroundColor: Colors.orange[50],
                labelStyle: TextStyle(color: Colors.orange[700]),
                materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
                visualDensity: VisualDensity.compact,
              )),
            // 传统地区字段作为备选
            if (d.countries.isEmpty && (d.area ?? '').isNotEmpty) 
              Chip(
                label: Text(d.area!, style: TextStyle(fontSize: isCompact ? 11 : 12)),
                materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
                visualDensity: VisualDensity.compact,
              ),
            if ((d.remarks ?? '').isNotEmpty) 
              Chip(
                label: Text(d.remarks!, style: TextStyle(fontSize: isCompact ? 11 : 12)),
                materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
                visualDensity: VisualDensity.compact,
              ),
          ],
        ),
        const SizedBox(height: 8),
        
        // // 导演信息
        // if (d.directors.isNotEmpty)
        //   Text(
        //     '导演：${d.directors.map((dir) => dir.name).join('、')}',
        //     maxLines: isCompact ? 1 : null,
        //     overflow: isCompact ? TextOverflow.ellipsis : null,
        //   )
        // else if ((d.director ?? '').isNotEmpty)
        //   Text(
        //     '导演：${d.director!}',
        //     maxLines: isCompact ? 1 : null,
        //     overflow: isCompact ? TextOverflow.ellipsis : null,
        //   ),
        
        // // 主演信息
        // if (d.casts.isNotEmpty)
        //   Text(
        //     '主演：${d.casts.take(3).map((cast) => cast.name).join('、')}',
        //     maxLines: isCompact ? 1 : null,
        //     overflow: isCompact ? TextOverflow.ellipsis : null,
        //   )
        // else if ((d.actor ?? '').isNotEmpty)
        //   Text(
        //     '主演：${d.actor!}',
        //     maxLines: isCompact ? 1 : null,
        //     overflow: isCompact ? TextOverflow.ellipsis : null,
        //   ),
        
        const SizedBox(height: 8),
        
        // 简介
        if ((d.summary ?? '').isNotEmpty)
          Text(
            d.summary!, 
            maxLines: isCompact ? 3 : 5, 
            overflow: TextOverflow.ellipsis,
          )
        else if ((d.content ?? '').isNotEmpty)
          Text(
            d.content!, 
            maxLines: isCompact ? 3 : 5, 
            overflow: TextOverflow.ellipsis,
          ),
      ],
    );
  }

  /// 构建友好的加载提示组件
  Widget _buildLoadingWidget() {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          // 自定义加载动画
          Container(
            width: 80,
            height: 80,
            decoration: BoxDecoration(
              color: Colors.white,
              borderRadius: BorderRadius.circular(16),
              boxShadow: [
                BoxShadow(
                  color: Colors.black.withOpacity(0.1),
                  blurRadius: 20,
                  offset: const Offset(0, 4),
                ),
              ],
            ),
            child: const Center(
              child: CircularProgressIndicator(
                strokeWidth: 3,
                valueColor: AlwaysStoppedAnimation<Color>(Colors.red),
              ),
            ),
          ),
          const SizedBox(height: 24),
          
          // 加载文字提示
          Text(
            widget.keyword != null ? '正在搜索影片详情...' : '正在加载影片详情...',
            style: TextStyle(
              fontSize: 16,
              fontWeight: FontWeight.w500,
              color: Colors.grey[700],
            ),
          ),
          const SizedBox(height: 8),
          
          // 副标题提示
          Text(
            widget.keyword != null 
                ? '正在获取数据，请稍候'
                : '正在获取详细信息，请稍候',
            style: TextStyle(
              fontSize: 14,
              color: Colors.grey[500],
            ),
          ),
          
          const SizedBox(height: 32),
          
          // 加载进度点
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: List.generate(3, (index) {
              return Container(
                margin: const EdgeInsets.symmetric(horizontal: 4),
                child: AnimatedContainer(
                  duration: Duration(milliseconds: 600 + (index * 200)),
                  curve: Curves.easeInOut,
                  width: 8,
                  height: 8,
                  decoration: BoxDecoration(
                    color: Colors.red.withOpacity(0.3 + (index * 0.2)),
                    borderRadius: BorderRadius.circular(4),
                  ),
                ),
              );
            }),
          ),
        ],
      ),
    );
  }

  /// 执行全站搜索
  Future<void> _performGlobalSearch() async {
    if (_detail?.name == null) return;
    
    setState(() {
      _isSearching = true;
      _searchResults = [];
      _searchTotal = 0;
      _searchDone = 0;
    });
  
    //计算耗时
    final stopwatch = Stopwatch()..start();
    try {
      final searchTasks = <Future<List<VodDetail>>>[];
      
      // 为每个视频站点创建搜索任务
      final y = (_detail!.year ?? '').trim();
      for (final site in kVideoSites) {
        searchTasks.add(_searchFromSite(site, _detail!.name, year: y.isEmpty ? null : y));
      }
      
      _searchTotal = searchTasks.length;
      final observedTasks = searchTasks
          .map((f) => f.whenComplete(() {
                if (mounted) {
                  setState(() {
                    _searchDone += 1;
                  });
                }
              }))
          .toList();
      // 并发执行所有搜索任务（带进度统计）
      final results = await Future.wait(observedTasks);
      // 收集所有有播放源的结果
      final allResults = <VodDetail>[];
      for (final siteResults in results) {
        for (final result in siteResults) {
          // 打印搜索结果的来源站点名
          print('站点 ${result.siteName ?? '未知站点'} 搜索结果: ${result.name} ${result.year ?? ''}');
          if (result.playSources.isNotEmpty) {
            allResults.add(result);
          }
        }
      }
      
      setState(() {
        _searchResults = allResults;
        _isSearching = false;
        _searchDone = _searchTotal;
      });
      
      if (allResults.isNotEmpty) {
        // 跳转到播放页面
        _navigateToPlayer(allResults);
      } else {
        _showNoSourceDialog();
      }
    } catch (e) {
      setState(() => _isSearching = false);
      _showSearchErrorDialog(e.toString());
    }
    print('搜索耗时: ${stopwatch.elapsedMilliseconds} ms');
  }

  String _normalizeTitle(String s) {
    return s.trim().toLowerCase().replaceAll(RegExp(r'\s+'), ' ');
  }

  String? _extractYear(String? s) {
    if (s == null) return null;
    final m = RegExp(r'(19|20)\d{2}').firstMatch(s);
    return m?.group(0);
  }

  /// 从指定站点搜索
  Future<List<VodDetail>> _searchFromSite(VideoSite site, String keyword, {String? year}) async {
    try {
      final service = ApiService(site);
      final searchResults = await service.fetchList(keyword: keyword, page: 1);
      if (searchResults.isEmpty) return [];
      final target = _normalizeTitle(keyword);
      final targetYear = _extractYear(year);
      final exact = searchResults.where((item) {
        final nameMatch = _normalizeTitle(item.name) == target;
        if (!nameMatch) return false;
        final itemYear = _extractYear(item.year);
        if (targetYear != null && itemYear != null) return itemYear == targetYear;
        return true;
      }).toList();
      if (exact.isEmpty) return [];
      final detail = await service.fetchDetail(exact.first.id);
      if (detail == null) return [];
      for (final src in detail.playSources) {
        src.episodes.removeWhere((ep) {
          final u = ep.url.trim().toLowerCase();
          final isHttp = u.startsWith('http://') || u.startsWith('https://');
          if (!isHttp) return true;
          final isVideoLike = u.contains('m3u8') || u.contains('hls') ||
              u.endsWith('.mp4') || u.endsWith('.mkv') || u.endsWith('.avi') ||
              u.endsWith('.flv') || u.endsWith('.ts') || u.endsWith('.mov') ||
              u.endsWith('.rmvb');
          return !isVideoLike;
        });
      }
      detail.playSources.removeWhere((src) => src.episodes.isEmpty);
      return detail.playSources.isNotEmpty ? [detail] : [];
    } catch (e) {
      print('站点 ${site.name} 搜索错误: $e');
      return [];
    }
  }

  /// 跳转到播放页面
  Future<void> _navigateToPlayer(List<VodDetail> results) async {
    if (results.isEmpty) return;
    // 聚合所有站点的播放源
    final allSources = _aggregateAllPlaySources(results);
    if (allSources.isEmpty) {
      _showNoSourceDialog();
      return;
    }

    // 选择默认“最清晰、网速最佳”的播放源（取该源的第一个剧集）
    final rankedSources = await _pickBestSource(allSources);
    final bestSource = rankedSources.first;
    final bestEpisode = (bestSource.episodes.isNotEmpty)
        ? bestSource.episodes.first
        : allSources.first.episodes.first;

    // 使用第一个结果的名称作为展示名称
    final displayName = results.first.name;

    Navigator.of(context).push(
      MaterialPageRoute(
        builder: (_) => PlayerPage(
          title: '$displayName · ${bestEpisode.title}',
          name: displayName,
          url: bestEpisode.url,
          cover: _detail?.pic, // 使用当前详情页的封面图
          year: _detail?.year,
          sourceSite: bestSource.siteName,
          playSources: rankedSources,
        ),
      ),
    );
  }

  /// 将多个站点返回的播放源进行聚合
  List<PlaySource> _aggregateAllPlaySources(List<VodDetail> results) {
    final out = <PlaySource>[];
    for (final r in results) {
      for (final s in r.playSources) {
        out.add(s);
      }
    }
    // 轻度去重：按“站点名+源名+剧集数量”去重
    final seen = <String>{};
    final dedup = <PlaySource>[];
    for (final s in out) {
      final key = '${s.siteName ?? ''}|${s.name}|${s.episodes.length}';
      if (!seen.contains(key)) {
        seen.add(key);
        dedup.add(s);
      }
    }
    return dedup;
  }

  /// 选择最清晰、网速最好的播放源
  Future<List<PlaySource>> _pickBestSource(List<PlaySource> sources) async {
    bool _isHlsLike(String url) {
      final u = url.toLowerCase();
      return u.contains('m3u8') || u.contains('hls');
    }

    Future<Map<String, dynamic>> _probeEpisode(PlayEpisode ep) async {
      final uri = Uri.tryParse(ep.url);
      if (uri == null) {
        return {'ok': false, 'latency': 2000, 'code': 0, 'type': null};
      }
      final sw = Stopwatch()..start();
      try {
        if (_isHlsLike(ep.url)) {
          final resp = await http
              .get(uri, headers: {
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0 Safari/537.36',
                'Accept': 'application/x-mpegURL,text/plain,*/*',
              })
              .timeout(const Duration(seconds: 1));
          final ms = sw.elapsedMilliseconds;
          final body = resp.body;
          final type = resp.headers['content-type'];
          final ok = resp.statusCode == 200 && (body.contains('#EXTM3U') || (type != null && type.toLowerCase().contains('mpegurl')));
          return {'ok': ok, 'latency': ms, 'code': resp.statusCode, 'type': type};
        } else {
          http.Response resp;
          try {
            resp = await http
                .head(uri, headers: {
                  'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0 Safari/537.36',
                  'Accept': 'video/*;q=0.9,*/*;q=0.8',
                })
                .timeout(const Duration(seconds: 1));
          } catch (_) {
            resp = await http
                .get(uri, headers: {
                  'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0 Safari/537.36',
                  'Accept': 'video/*;q=0.9,*/*;q=0.8',
                  'range': 'bytes=0-0',
                })
                .timeout(const Duration(seconds: 1));
          }
          final ms = sw.elapsedMilliseconds;
          final type = resp.headers['content-type'] ?? '';
          final code = resp.statusCode;
          final ok = (code == 200 || code == 206) && (type.toLowerCase().startsWith('video/') || type.toLowerCase().contains('octet-stream'));
          return {'ok': ok, 'latency': ms, 'code': code, 'type': type};
        }
      } catch (_) {
        return {'ok': false, 'latency': 2000, 'code': 0, 'type': null};
      }
    }

    int qualityScore(PlaySource s) {
      int score = 0;
      String text = '${s.siteName ?? ''} ${s.name} ';
      final first = s.episodes.isNotEmpty ? s.episodes.first : null;
      if (first != null) {
        text += '${first.title} ${first.url}';
        if (first.url.startsWith('https://')) score += 2;
        final lowerUrl = first.url.toLowerCase();
        if (lowerUrl.contains('m3u8') || lowerUrl.contains('hls')) score += 6;
        if (lowerUrl.contains('.mp4')) score += 3;
        if (lowerUrl.contains('.flv')) score -= 3;
      }
      final kw = {
        '4k': 10,
        '2160': 10,
        '蓝光': 9,
        'bd': 7,
        '超清': 8,
        '1080': 8,
        'hd': 6,
        '标清': -5,
        'sd': -4,
        'rmvb': -6,
        'cam': -8,
        'TS': -7,
        '抢先': -4,
        '预告': -6,
        'yun': 2,
        'dbm3u8': 3,
      };
      final lower = text.toLowerCase();
      kw.forEach((k, v) {
        if (lower.contains(k.toLowerCase())) score += v;
      });
      if (s.name.length <= 8) score += 1;
      if (s.episodes.length >= 30) score += 1;
      return score;
    }

    final tasks = <Future<MapEntry<PlaySource, int>>>[];
    for (final s in sources) {
      tasks.add(() async {
        final first = s.episodes.isNotEmpty ? s.episodes.first : null;
        int latency = 2000;
        bool ok = false;
        if (first != null) {
          final pr = await _probeEpisode(first);
          latency = pr['latency'] as int;
          ok = pr['ok'] as bool;
        }
        final base = qualityScore(s);
        final latScore = ok ? (100 - (latency ~/ 10)) : -2000;
        final total = base + latScore;
        return MapEntry(s, total);
      }());
    }
    final scored = await Future.wait(tasks);
    scored.sort((a, b) => b.value.compareTo(a.value));
    return scored.map((e) => e.key).toList();
  }

  /// 显示无播放源对话框
  void _showNoSourceDialog() {
    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        title: const Text('未找到播放源'),
        content: const Text('很抱歉，暂时没有找到可用的播放资源。请稍后再试或尝试其他影片。'),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(context),
            child: const Text('确定'),
          ),
        ],
      ),
    );
  }

  /// 显示搜索错误对话框
  void _showSearchErrorDialog(String error) {
    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        title: const Text('搜索失败'),
        content: Text('搜索播放源时发生错误：$error'),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(context),
            child: const Text('确定'),
          ),
        ],
      ),
    );
  }

  /// 构建播放按钮
  Widget _buildPlayButton() {
    return Card(
      elevation: 4,
      color: Colors.white,
      shadowColor: Colors.black.withOpacity(0.1),
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
      child: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            Row(
              children: [
                const Icon(Icons.play_circle_filled, color: Colors.red, size: 28),
                const SizedBox(width: 12),
                Text(
                  '播放影片',
                  style: Theme.of(context).textTheme.titleLarge?.copyWith(
                    fontWeight: FontWeight.bold,
                  ),
                ),
              ],
            ),
            const SizedBox(height: 16),
            ElevatedButton.icon(
              onPressed: _isSearching ? null : _performGlobalSearch,
              icon: _isSearching 
                ? const SizedBox(
                    width: 20,
                    height: 20,
                    child: CircularProgressIndicator(strokeWidth: 2),
                  )
                : const Icon(Icons.play_arrow, size: 20),
              label: Text(_isSearching ? '正在搜索播放源...' : '在线观看'),
              style: ElevatedButton.styleFrom(
                backgroundColor: Colors.red[600],
                foregroundColor: Colors.white,
                padding: const EdgeInsets.symmetric(vertical: 16),
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(12),
                ),
                elevation: 2,
              ),
            ),
            if (_isSearching) ...[
              const SizedBox(height: 12),
              ClipRRect(
                borderRadius: BorderRadius.circular(8),
                child: SizedBox(
                  height: 20,
                  child: Stack(
                    children: [
                      Positioned.fill(
                        child: Center(
                          child: LinearProgressIndicator(
                            minHeight: 18,
                            backgroundColor: Colors.black12,
                            value: _searchTotal > 0 ? (_searchDone / _searchTotal).clamp(0.0, 1.0) : null,
                            valueColor: AlwaysStoppedAnimation<Color>(Colors.red),
                          ),
                        ),
                      ),
                      Align(
                        alignment: Alignment(
                          -1.0 + 2.0 * ((_searchTotal > 0 ? (_searchDone / _searchTotal) : 0.0).clamp(0.0, 1.0)),
                          0.0,
                        ),
                        child: Container(
                          padding: const EdgeInsets.symmetric(horizontal: 4),
                          child: Text(
                            '${_searchTotal > 0 ? ((_searchDone * 100) ~/ _searchTotal) : 0}%',
                            style: const TextStyle(
                              color: Colors.white,
                              fontSize: 16,
                              fontWeight: FontWeight.bold,
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),
                ),
              ),
              const SizedBox(height: 8),
              Text(
                '正在从多个视频站点搜索播放资源，请稍候...',
                style: TextStyle(
                  color: Colors.grey[600],
                  fontSize: 14,
                ),
                textAlign: TextAlign.center,
              ),
            ],
          ],
        ),
      ),
    );
  }
}
